﻿//---------------------------------------------------------------------------
//
// Copyright (C) Inter Access B.V..  All rights reserved.
//
//---------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using Schedule.Primitives;
using System.Reflection;

namespace Schedule
{
    /// <summary>
    /// Control for displaying appointment information
    /// </summary>
    public class Schedule : Control
    {
        static Schedule()
        {
            // Override default styles
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Schedule), new FrameworkPropertyMetadata(typeof(Schedule)));
            // We need to change this
            TimePanel.DefaultStyleKeyProperty.OverrideMetadata(typeof(TimePanel), new FrameworkPropertyMetadata(typeof(TimePanel)));

            // Hook up events
            EventManager.RegisterClassHandler(typeof(Schedule), TimeItem.MouseDownEvent, new RoutedEventHandler(OnTimeItemMouseDown));
            EventManager.RegisterClassHandler(typeof(Schedule), TimeItem.MouseMoveEvent, new RoutedEventHandler(OnTimeItemMouseMove));
            EventManager.RegisterClassHandler(typeof(Schedule), TimeItem.MouseUpEvent, new RoutedEventHandler(OnTimeItemMouseUp));
            EventManager.RegisterClassHandler(typeof(Schedule), TimeItem.DragEnterEvent, new RoutedEventHandler(OnTimeItemDragEnter));
            EventManager.RegisterClassHandler(typeof(Schedule), TimeItem.DragLeaveEvent, new RoutedEventHandler(OnTimeItemDragLeave));
            EventManager.RegisterClassHandler(typeof(Schedule), TimeItem.DragOverEvent, new RoutedEventHandler(OnTimeItemDragOver));
            EventManager.RegisterClassHandler(typeof(Schedule), TimeItem.DropEvent, new RoutedEventHandler(OnTimeItemDrop));
        }

        public Schedule()
        {
            // Create a new observalble collection for appointments
            // in the future change this to object
            Appointments = new ObservableCollection<Appointment>();
            HeaderItems = new ObservableCollection<ScheduleHeaderItem>();
            DisplayedDates = new ObservableCollection<DateTime>();
        }

        protected override void OnInitialized(EventArgs e)
        {
            // Rebuild the header items
            RebuildHeader();

            base.OnInitialized(e);
        }

        #region Layout Dependency Properties

        public Double HeaderHeight
        {
            get { return (Double)GetValue(HeaderHeightProperty); }
            set { SetValue(HeaderHeightProperty, value); }
        }

        public static readonly DependencyProperty HeaderHeightProperty =
            DependencyProperty.Register("HeaderHeight", typeof(Double), typeof(Schedule), new UIPropertyMetadata(150d));

        public Double HeaderWidth
        {
            get { return (Double)GetValue(HeaderWidthProperty); }
            set { SetValue(HeaderWidthProperty, value); }
        }

        public static readonly DependencyProperty HeaderWidthProperty =
            DependencyProperty.Register("HeaderWidth", typeof(Double), typeof(Schedule), new UIPropertyMetadata(150d));

        #endregion

        #region Logical Dependency Properties

        public ObservableCollection<Appointment> Appointments
        {
            get { return (ObservableCollection<Appointment>)GetValue(AppointmentsProperty); }
            set { SetValue(AppointmentsProperty, value); }
        }

        public static readonly DependencyProperty AppointmentsProperty =
            DependencyProperty.Register("Appointments", typeof(ObservableCollection<Appointment>), typeof(Schedule), new UIPropertyMetadata());

        public ObservableCollection<DateTime> DisplayedDates
        {
            get { return (ObservableCollection<DateTime>)GetValue(DisplayedDatesProperty); }
            set { SetValue(DisplayedDatesProperty, value); }
        }

        public static readonly DependencyProperty DisplayedDatesProperty =
            DependencyProperty.Register("DisplayedDates", typeof(ObservableCollection<DateTime>), typeof(Schedule), new UIPropertyMetadata());

        public TimeItemSize ItemSize
        {
            get { return (TimeItemSize)GetValue(ItemSizeProperty); }
            set { SetValue(ItemSizeProperty, value); }
        }

        public static readonly DependencyProperty ItemSizeProperty =
            DependencyProperty.Register("ItemSize", typeof(TimeItemSize), typeof(Schedule),
            new FrameworkPropertyMetadata(TimeItemSize.OneHour, OnItemSizePropertyChanged)
            {
                AffectsArrange = true,
                AffectsMeasure = true
            }
            );

        private static void OnItemSizePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            Schedule schedule = (Schedule)sender;
            schedule.RebuildHeader();
        }

        public ObservableCollection<ScheduleHeaderItem> HeaderItems
        {
            get { return (ObservableCollection<ScheduleHeaderItem>)GetValue(HeaderItemsProperty); }
            set { SetValue(HeaderItemsProperty, value); }
        }

        public static readonly DependencyProperty HeaderItemsProperty =
            DependencyProperty.Register("HeaderItems", typeof(ObservableCollection<ScheduleHeaderItem>), typeof(Schedule), new UIPropertyMetadata());

        public DataTemplate AppointmentTemplate
        {
            get { return (DataTemplate)GetValue(AppointmentTemplateProperty); }
            set { SetValue(AppointmentTemplateProperty, value); }
        }

        public static readonly DependencyProperty AppointmentTemplateProperty =
            DependencyProperty.Register("AppointmentTemplate", typeof(DataTemplate), typeof(Schedule), new UIPropertyMetadata());

        #endregion

        #region Attached Properties

        

        #endregion

        #region Methods

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
        }

        /// <summary>
        /// Fills the header with header items
        /// </summary>
        internal void RebuildHeader()
        {
            // Clear the current header items
            this.HeaderItems.Clear();

            // Set the work date
            DateTime workingDate = new DateTime(1, 1, 1);
            DateTime workingEndDate = workingDate.AddDays(1);

            // While we need to generate headers
            while (workingDate < workingEndDate)
            {
                // Generate headers!
                ScheduleHeaderItem item = new ScheduleHeaderItem();
                TimePanel.SetItemStart(item, workingDate);
                // Set the size according to the itemsize
                TimePanel.SetItemEnd(item, workingDate.AddSeconds((int)this.ItemSize));
                HeaderItems.Add(item);
                
                // Add up the working date to next Item
                workingDate = workingDate.AddSeconds((int)this.ItemSize);
            }
        }

        #endregion

        #region Eventhandlers

        private static void OnTimeItemMouseUp(object sender, RoutedEventArgs e)
        {

        }

        private static void OnTimeItemMouseMove(object sender, RoutedEventArgs e)
        {

        }

        private static void OnTimeItemMouseDown(object sender, RoutedEventArgs e)
        {

        }

        private static void OnTimeItemDragEnter(object sender, RoutedEventArgs e)
        {

        }

        private static void OnTimeItemDragLeave(object sender, RoutedEventArgs e)
        {

        }

        private static void OnTimeItemDragOver(object sender, RoutedEventArgs e)
        {

        }

        private static void OnTimeItemDrop(object sender, RoutedEventArgs e)
        {

        }

        #endregion
    }
}
